﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
using System.Drawing.Drawing2D;
using MoneyWentWhere.DataModel;
using MoneyWentWhere.WinFormsUI.Properties;
using System.Diagnostics;

namespace MoneyWentWhere.WinFormsUI.UI.DataGrid
{
    class TxDataGridPainter
    {
        readonly DataGridView DataGrid;

        int _mouseOverRow = -1;

        public TxDataGridPainter(DataGridView dataGrid)
        {
            if (dataGrid == null) { throw new ArgumentNullException("dataGrid"); }
            DataGrid = dataGrid;

            DataGrid.CellPainting += DataGrid_CellPainting;

        }

        public int MouseOverRow
        {
            get { return _mouseOverRow; }
            set
            {
                if (_mouseOverRow == value) { return; }

                int oldRow = _mouseOverRow;
                _mouseOverRow = value;

                if (oldRow >= 0 && oldRow < DataGrid.Rows.Count)
                {
                    DataGrid.InvalidateRow(oldRow);
                }
                if (_mouseOverRow >= 0 && _mouseOverRow < DataGrid.Rows.Count)
                {
                    DataGrid.InvalidateRow(_mouseOverRow);
                }
            }
        }

        private void DataGrid_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
        {
            if (e.RowIndex == _mouseOverRow)
            {
                e.CellStyle.BackColor =
                    Settings.Default.Color_TxSelect;
            }

            e.PaintBackground(e.ClipBounds, true);

            if (e.RowIndex >= 0)
            {
                Transaction tx = DataGrid.Rows[e.RowIndex].DataBoundItem as Transaction;
                if (tx != null) { PaintBackground(tx, e); }
            }

            e.PaintContent(e.ClipBounds);
            e.Handled = true;
        }

        LinearGradientBrush _brushReconcile;

        LinearGradientBrush _brushTransferIn;
        LinearGradientBrush _brushTransferOut;

        void CreateBrushes(DataGridViewCellPaintingEventArgs e)
        {
            if (e.ColumnIndex == DataGrid.Columns.Count - 2)
            {
                CreateHorizontalGradient(ref _brushReconcile, e.CellBounds,
                    DataGrid.RowsDefaultCellStyle.BackColor,
                    Settings.Default.Color_TxReconcile);

                CreateHorizontalGradient(ref _brushTransferIn, e.CellBounds,
                    DataGrid.RowsDefaultCellStyle.BackColor,
                    Settings.Default.Color_TxTransfer);

                CreateHorizontalGradient(ref _brushTransferOut, e.CellBounds,
                    Settings.Default.Color_TxTransfer,
                    DataGrid.RowsDefaultCellStyle.BackColor);
            }
        }

        void CreateHorizontalGradient(ref LinearGradientBrush brush,
             Rectangle cellBounds, Color c1, Color c2)
        {
            // BUGFIX: -1 since 1 green pixel was showing to the left
            if (brush == null ||
                brush.Rectangle.X != cellBounds.X - 1 ||
                brush.Rectangle.Width != cellBounds.Width + 2)
            {
                if (brush != null)
                {
                    Trace.WriteLine("Brush bounds changed. " + brush.Rectangle + " != " + cellBounds);
                    brush.Dispose();
                }

                brush = new LinearGradientBrush(
                    new Rectangle(
                        cellBounds.X - 1,
                        cellBounds.Y,
                        cellBounds.Width + 2,
                        cellBounds.Height),
                    c1,
                    c2,
                    LinearGradientMode.Horizontal);
            }
        }

        Rectangle GetReconcileRectangle(Rectangle cellBounds)
        {
            int lineHeight = 3;
            return new Rectangle(
                cellBounds.X,
                cellBounds.Bottom - lineHeight,
                cellBounds.Width,
                lineHeight);
        }

        void PaintBackground(Transaction tx, DataGridViewCellPaintingEventArgs e)
        {
            CreateBrushes(e);

            bool isSettingsColumn = (e.ColumnIndex == DataGrid.Columns.Count - 2);

            if (tx.Kind == TransactionKind.Reconcile)
            {                
                if (e.ColumnIndex == DataGrid.Columns.Count -1)
                {
                    e.CellStyle.BackColor = Settings.Default.Color_TxReconcile;
                    e.CellStyle.ForeColor = Color.White;
                    e.PaintBackground(e.ClipBounds, false);
                }
                else if (isSettingsColumn)
                {
                    e.Graphics.FillRectangle(_brushReconcile, e.CellBounds);
                    DrawImage(Resources.pin_on_green, 0, e);
                }
            }
            else if (tx.Kind == TransactionKind.Transfer)
            {
                if (isSettingsColumn)
                {
                    if (tx.Amount > 0)
                    {
                        // Transfer IN
                        e.Graphics.FillRectangle(_brushTransferIn, e.CellBounds);
                        DrawImage(Resources.transfer_active_in, 0, e);
                    }
                    else
                    {
                        // Transfer OUT
                        e.Graphics.FillRectangle(_brushTransferOut, e.CellBounds);
                        DrawImage(Resources.transfer_active_out, 0, e);
                    }
                }
            }
            else if (isSettingsColumn && e.RowIndex == _mouseOverRow)
            {
                DrawImage(Resources.pin_off, 0, e);
                DrawImage(Resources.transfer_off, 1, e);
            }

        }

        void DrawImage(Image image, int position, DataGridViewCellPaintingEventArgs e)
        {
            e.Graphics.DrawImage(image,
                e.CellBounds.Right - ((image.Width + 6) * (position + 1)),
                e.CellBounds.Top + 3,
                image.Width,
                image.Height);
        }

    }
}
